package org.ourgrid.gridMonitor;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Timer;

import org.ourgrid.gridMonitor.operations.BrokerLocalOperation;
import org.ourgrid.gridMonitor.operations.PeerLocalOperation;
import org.ourgrid.gridMonitor.operations.WorkerLocalOperation;

public class GridMonitorSpy extends Thread{

	private static boolean ativo = true;
	private static boolean wasCommunicated = false;
	public GridMonitorSpy(int tipoMonitorado, int portaComunicacao){
		Componente.tipoMonitorado = tipoMonitorado;
		Componente.portaComunicacao = portaComunicacao;
		Componente.timer = new Timer();
	}
	
	public void run(){
        executarMonitor();
	}
	
	private void executarMonitor(){
		BufferedReader entrada=null;
        Socket socket = null;
        System.out.println("Porta testada: " + Componente.portaComunicacao);

        while(true){
			   try{
				   if((LocalComponentInformation.available) &&(!wasCommunicated)){ //Se estiver ativo, tenta a conexão...
					   if(Componente.tipoMonitorado == TipoMonitorado.PEER){
				           PeerLocalOperation.connect(Componente.tipoMonitorado,Componente.portaComunicacao); //Try to connect with the Grid Monitor...
					   } else if (Componente.tipoMonitorado == TipoMonitorado.BROKER){
						   BrokerLocalOperation.connect(Componente.tipoMonitorado,Componente.portaComunicacao); //Try to connect with the Grid Monitor...
					   } else if (Componente.tipoMonitorado == TipoMonitorado.WORKER){
						   WorkerLocalOperation.connect(Componente.tipoMonitorado,Componente.portaComunicacao); //Try to connect with the Grid Monitor...
					   }
					   wasCommunicated = true;
					   //Só inicia o timer se o hamster for encontrado.
					   //Componente.timer.schedule(new HamsterRecuperation(), 30000);
				       break;
				   }
			   }catch(IOException io){
				  try {
					System.out.println("Failure trying to send a message");
					Thread.sleep(10000);
				  } catch (InterruptedException e) {
				       continue;
				  }
			   }
		}
        
        while(true){
            try{
	                 //Mantem uma porta aberta para escutar as requisições do GridMonitor
	                 ServerSocket serv = new ServerSocket(Componente.portaComunicacao);
				     System.out.println("Porta testada: " + Componente.portaComunicacao);
	                 
		             System.out.println("Aguardando Mensagem/Solicitação...");
		       		 //Aguarda uma conexão na porta especificada e cria retorna o socket que irá comunicar com o cliente  
		             socket = serv.accept();
		             
			         //Cria um BufferedReader para o canal da stream de entrada de dados do socket s  
			         entrada = new BufferedReader(new InputStreamReader(socket.getInputStream()));  
			         
			         //Aguarda por algum dado e imprime a linha recebida quando recebe
			         String msgEntrada = entrada.readLine();
			         
			         String[] mensagem = msgEntrada.split(Componente.separador);
			         ativo = true;
			         
			         if(Componente.tipoMonitorado == TipoMonitorado.BROKER){
			             BrokerLocalOperation.processRequest(mensagem);
			         } else if(Componente.tipoMonitorado == TipoMonitorado.PEER){
			        	 PeerLocalOperation plo = new PeerLocalOperation(mensagem);
			        	 plo.start();
			         }  
				}catch(IOException e){ //Trata possíveis exceções
		        	   System.out.println("IOException - GridMonitorSpy: " + e.getMessage());
		        	   System.out.println("O GM ainda não está conectado ou não está escutando a porta informada");
		        	   try {
						 Thread.sleep(10000);
						 Componente.portaComunicacao++;
		        	   } catch (InterruptedException e1) {
						 e1.printStackTrace();
					   }
			}
         }
	}
	
	public static boolean isActive(){
		return ativo;
	}
}
